package net.danielthompson.danray;

import net.danielthompson.danray.structures.Scene;
import net.danielthompson.danray.ui.CountCanvas;
import net.danielthompson.danray.ui.MainCanvas;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.Timer;


/**
 * DanRay
 * User: dthompson
 * Date: 6/28/13
 * Time: 10:32 AM
 */
public class Main {
   static final int X = 480 , Y = 270;
   static final int MaxDepth = 16;
   static final int SamplesPerPixel = 5;
   static final int SuperSamplesPerPixel = 20;
   static final int AirIndexOfRefraction = 1;
   static final int Threads = 4;

   static BufferedImage bufferedImage = new BufferedImage(X, Y, BufferedImage.TYPE_INT_RGB);
   static BufferedImage rayCountImage = new BufferedImage(X, Y, BufferedImage.TYPE_INT_RGB);

   public static boolean Finished = false;

   static MainCanvas canvas;
   static CountCanvas countCanvas;
   static Frame frame;
   static Frame countFrame;
   static Scene scene;

   static TraceManager traceManager;

   static public void main(String[] args) {

      canvas = new MainCanvas(bufferedImage);
      canvas.addMouseListener(canvas);


      frame = new Frame("DanRay");
      frame.add("Center", canvas);
      frame.setSize(new Dimension(X, Y + 22));
      frame.setVisible(true);

      countCanvas = new CountCanvas(rayCountImage);
      countFrame = new Frame("Ray Density");
      countFrame.add("Center", countCanvas);
      countFrame.setSize(new Dimension(X, Y + 22));
      countFrame.setVisible(true);

      //scene = SceneBuilder.ManySpheres(X, Y);
      //scene = SceneBuilder.PlaneAndBox(X, Y);
      //scene = SceneBuilder.DepthOfFieldTest(X, Y);
      //Scene scene = SceneBuilder.ReflectiveSphereWithLights(X, Y);
      //Scene scene = SceneBuilder.ReflectiveTriangleMeshWithLight(X, Y);
      //Scene scene = SceneBuilder.FourReflectiveSphereWithLights(X, Y);
      Scene scene = SceneBuilder.FourReflectiveSphereWithLightsPointable(X, Y);
      //Scene scene = SceneBuilder.TwoSpheresWithLights(X, Y);
      //Scene scene = SceneBuilder.ShadowTest(X, Y);
      //Scene scene = SceneBuilder.TwoTransparentReflectiveSpheresWithLights(X, Y);

      traceManager = new TraceManager(Threads, bufferedImage, canvas, rayCountImage, countCanvas, scene, X, Y, MaxDepth, SamplesPerPixel, SuperSamplesPerPixel, AirIndexOfRefraction);
      Date start = new Date();
      traceManager.Trace();
      Date end = new Date();
      long milliseconds = end.getTime() - start.getTime();
      System.out.println("Finished rendering in " + milliseconds + " milliseconds.");
      SaveImage("image.png", "png");
   }

   public static void Retrace(int[] pixel) {
      traceManager.Trace(pixel);
   }

   public static void SaveImage(String filename, String type) {
      try {
         ImageIO.write(bufferedImage, type, new File(filename));
      }
      catch (IOException e) {
         System.err.println("image not saved.");
      }
   }
}